package com.xoms.admin.service.impl;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xoms.admin.aspect.datasource.DataSourceSwitcher;
import com.xoms.admin.cache.dao.ProCategoryCache;
import com.xoms.admin.controller.res.bean.RProCategoryBean;
import com.xoms.admin.controller.res.bean.RProCategoryJSONBean;
import com.xoms.admin.model.AccountBean;
import com.xoms.admin.model.ProCategoryBean;
import com.xoms.admin.model.vo.ProCategoryVo;
import com.xoms.admin.model.vo.TreeNodeBean;
import com.xoms.admin.persist.dao.ProCategoryDao;
import com.xoms.admin.service.ProCategoryService;
import com.xoms.admin.service.exception.ServiceException;
import com.xoms.util.AppTextUtil;
import com.xoms.util.DateTimeUtil;
import com.xoms.util.NumUtil;
import com.xoms.util.StringUtil;

@Service
public class ProCategoryServiceImpl implements ProCategoryService {
	
	Logger logger = Logger.getLogger(this.getClass());
	
	@Autowired
	ProCategoryDao proCategoryImpl;
	
	@Autowired
	ProCategoryCache proCategoryCacheImpl;
	
	@Override
	public RProCategoryJSONBean getAllCategories(AccountBean account) {
		RProCategoryJSONBean bean = new RProCategoryJSONBean();
		JSONArray jsonArray = new JSONArray();
		// 从缓存获取所有分类
		String cateStr = null;// proCategoryCacheImpl.getAllCategoresCache();
		if (StringUtil.isEmpty(cateStr)) {// redis内分类信息为空则从数据库查询分类
			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_HQ);
			List<ProCategoryVo> cates = proCategoryImpl.selectHqCates();
			
			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_XOMS);
			List<ProCategoryVo> cate2s = proCategoryImpl.selectAllCates();
			if(cate2s == null) {
				return null;
			}
			cates.addAll(cate2s);
		    logger.info("cates分类："+JSON.toJSONString(cates));
			// 构造根节点
			ProCategoryVo root = new ProCategoryVo();
			root.setCid("0");
			cates.add(root);
			// 根据父节点id分组
		    Map<String, List<ProCategoryVo>> map = cates.stream()
		            .filter(o -> Objects.nonNull(o.getParentId()))
		            .collect(Collectors.groupingBy(ProCategoryVo::getParentId));

		    //循环处理子节点 构建树状结构
		    cates.forEach(proCategory -> {
		        if (map.containsKey(proCategory.getCid())) {
		        		proCategory.setSubCategories(map.get(proCategory.getCid()));
		        }
		    });
			// 获取根节点下的所有服务项
		    ProCategoryVo result = cates.stream()
		    		.filter(proCategory -> "0".equals(proCategory.getCid())).findFirst().orElse(null);
			String catesJson = JSON.toJSONString(result.getSubCategories(), SerializerFeature.WriteMapNullValue);
		    logger.info("cates分类：" + catesJson);
			jsonArray = JSON.parseArray(catesJson);
			// 将分类存入缓存
			//proCategoryCacheImpl.setAllCategoryCache(catesJson);
		} else {
			jsonArray = JSON.parseArray(cateStr);
		}
		bean.setCategory(jsonArray);
		return bean;
	}

	@Override
	public RProCategoryBean edit(AccountBean account, String cid, String name, String parentId) {
		boolean flag = false;
		ProCategoryBean data = new ProCategoryBean();
		data.setName(name);
		data.setParentId(parentId);
		data.setLevel(3);
		// 获取当前分类下最大顺序，+1
		int cateSort = NumUtil.toInt(proCategoryImpl.selectMaxSort(parentId), 0);
		data.setSort(cateSort + 1);
		data.setIsHq(0);// 非总部分类
		// TODO：判断父节点id是不是第二级
		
		if (StringUtil.isEmpty(cid)) {// 新建
			// 新建时验证分类名称是否已存在
			ProCategoryBean temp = proCategoryImpl.selectOneByName(name);
			if (temp != null) {
				throw new ServiceException("category_name_is_exist");
			}

			cid = AppTextUtil.getPrimaryKey();// id
			data.setCid(cid);
			data.setAccountId(account.getAccid());
			flag = proCategoryImpl.insert(data) > 0;
			if (!flag) {
				throw new ServiceException("database_insert_fail","商品分类");
			}
		} else {
			data.setCid(cid);
			flag = proCategoryImpl.update(data) > 0;// 更新数据库
			if (!flag) {
				throw new ServiceException("database_update_fail","商品分类");
			}
		}
		// 清除缓存
		proCategoryCacheImpl.setAllCategoryCache(null);
		proCategoryCacheImpl.clearCategoryCache();
		return parse(proCategoryImpl.selectOneById(cid));
	}
	
	/**
	 * 格式化分类数据
	 * @param selectOneById
	 * @return
	 */
	private RProCategoryBean parse(ProCategoryBean cate) {
		RProCategoryBean res = new RProCategoryBean();
		res.setAccount(cate.getAccount());
		res.setCid(cate.getCid());
		res.setLevel(cate.getLevel());
		res.setSort(cate.getSort());
		res.setParentId(cate.getParentId());
		res.setName(cate.getName());
		res.setIsHq(cate.getIsHq());
		res.setCreateTime(DateTimeUtil.formatTimestamp(cate.getCreateTime()));
		return res;
	}

	@Override
	public boolean del(AccountBean account, String cid) {
		// 删除商品分类是判断分类下有无商品，如有则无法删除
		int member = proCategoryImpl.selectCount2Category(cid);
		if(member > 0) {
			throw new ServiceException("category_had_connect_to_pro");
		}
		if (proCategoryImpl.del(cid) > 0) {// 删除分类
			proCategoryCacheImpl.setAllCategoryCache(null);
			proCategoryCacheImpl.clearCategoryCache();
			return true;
		}
		return false;
	}

	@Override
	public RProCategoryJSONBean getCategories(AccountBean account, int type) {
		RProCategoryJSONBean bean = new RProCategoryJSONBean();
		JSONArray jsonArray = new JSONArray();
		// 从缓存获取所有分类
		String cateStr = null;//proCategoryCacheImpl.getCategoresCache(type);
		if (StringUtil.isEmpty(cateStr)) {// redis内分类信息为空则从数据库查询分类

			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_HQ);
			
			List<TreeNodeBean> cates = proCategoryImpl.selectHqCateTrees(type);
			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_XOMS);
			
			List<TreeNodeBean> cates2 = null;
			
			if(type == 0) {
				cates2 = proCategoryImpl.selectCategores();
			} else {
				cates2 = proCategoryImpl.selectCategoresByPid(cates);
			}
			
			if(cates2 == null) {
				return null;
			}
			cates.addAll(cates2);
		    logger.info("cates分类："+JSON.toJSONString(cates));
			// 构造根节点
			TreeNodeBean root = new TreeNodeBean();
			root.setValue(type + "");
			cates.add(root);
			// 根据父节点id分组
		    Map<String, List<TreeNodeBean>> map = cates.stream()
		            .filter(o -> Objects.nonNull(o.getParentId()))
		            .collect(Collectors.groupingBy(TreeNodeBean::getParentId));

		    //循环处理子节点 构建树状结构
		    cates.forEach(proCategory -> {
		        if (map.containsKey(proCategory.getValue())) {
		        		proCategory.setChildren(map.get(proCategory.getValue()));
		        } 
		    });

		    logger.info("cates分类-------："+JSON.toJSONString(cates));
			// 获取根节点下的所有服务项
		    TreeNodeBean result = cates.stream()
		    		.filter(proCategory -> root.getValue().equals(proCategory.getValue())).findFirst().orElse(null);
			String catesJson = JSON.toJSONString(result.getChildren());
			jsonArray = JSON.parseArray(catesJson);
			// 将分类存入缓存
			//proCategoryCacheImpl.setCategoryCache(catesJson, type);
		} else {
			jsonArray = JSON.parseArray(cateStr);
		}
		bean.setCategory(jsonArray);
		return bean;
	}

	@Override
	public RProCategoryJSONBean getFirstCategories(AccountBean account) {
		RProCategoryJSONBean bean = new RProCategoryJSONBean();
		JSONArray jsonArray = new JSONArray();
		// 从缓存获取一级分类
		String cateStr = null;//proCategoryCacheImpl.getFirstCategoresCache();
		if (StringUtil.isEmpty(cateStr)) {// redis内分类信息为空则从数据库查询分类

			//手动切换数据源
			DataSourceSwitcher.setDataSourceType(DataSourceSwitcher.DATA_SOURCE_HQ);
			
			List<TreeNodeBean> cates = proCategoryImpl.selectHqFirstCateTrees();
			if(cates == null) {
				return null;
			}
		    logger.info("cates分类："+JSON.toJSONString(cates));
			String catesJson = JSON.toJSONString(cates);
			jsonArray = JSON.parseArray(catesJson);
			// 将分类存入缓存
			//proCategoryCacheImpl.setFirstCategoryCache(catesJson);
		} else {
			jsonArray = JSON.parseArray(cateStr);
		}
		bean.setCategory(jsonArray);
		return bean;
	}

	@Override
	public boolean editSorts2Category(String sorts) {
		boolean flag = false;
		List<String> sortList = JSON.parseArray(sorts, String.class);
		flag = proCategoryImpl.updateSorts(sortList) > 0;
		proCategoryCacheImpl.setAllCategoryCache(null);
		proCategoryCacheImpl.clearCategoryCache();
		return flag;
	}
	
}
